home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / xcdplayer / program.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  18KB  |  814 lines

  1. /*
  2.  * Copyright (C) 1990 Regents of the University of California.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of the University of
  9.  * California not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  the University of California makes no representations
  12.  * about the suitability of this software for any purpose.  It is provided
  13.  * "as is" without express or implied warranty.
  14.  */
  15.  
  16. # include <X11/Intrinsic.h>
  17. # include <X11/StringDefs.h>
  18. # include <X11/Shell.h>
  19. # include <X11/Xaw/Form.h>
  20. # include <X11/Xaw/Label.h>
  21. # include <X11/Xaw/List.h>
  22. # include <X11/Xaw/Command.h>
  23. # include <X11/Xaw/Toggle.h>
  24. # include <X11/Xaw/Viewport.h>
  25. # include <X11/Xaw/Dialog.h>
  26.  
  27.  
  28. # include <stdio.h>
  29. # include <string.h>
  30. # include <malloc.h>
  31.  
  32. # include "debug.h"
  33. # include "cdrom_globs.h"
  34. #ifdef sun
  35. # include "cdrom_sun.h"
  36. #endif
  37. #ifdef sgi
  38. # include "cdrom_sgi.h"
  39. #endif
  40.  
  41.  
  42. /* externally manipulated vars: */
  43. char    program_str[100];
  44. char    *disc_title = NULL;
  45.  
  46. static    Widget    program_form;
  47. static    Widget    program_display_form;
  48. static    Widget    program_anchor;
  49. static    Widget    trackbuttons[9];
  50. static    Widget    plus10_button;
  51. static    Widget    new_track_button;
  52. static    Boolean    adding_to_new_track = False;
  53. static    struct    prognode *current_node = NULL;
  54.  
  55. extern    void    cb_move_program_ptr();
  56.  
  57.  
  58. void
  59. program_form_setup (parent_widget)
  60.     Widget    parent_widget;
  61. {
  62.         Arg    args[10];
  63.     char    namestr[2];
  64.     int    i;
  65.  
  66.     Widget    program_display_viewport;
  67.     Widget    track_select_form;
  68.     Widget    clear_button;
  69.     Widget    cancel_button;
  70.     Widget    save_button;
  71.     Widget    all_button;
  72.  
  73.     extern    void    cb_clear_program();
  74.     extern    void    cb_cancel_program();
  75.     extern    void    cb_save_program();
  76.     extern    void    cb_trackbuttons();
  77.     extern    void    cb_add_10();
  78.     extern    void    cb_new_track();
  79.     extern    void    cb_program_all();
  80.  
  81.     /* 
  82.      * create program form as a non-managed widget, because this 
  83.      * form "pops up" when requested, as part of the main form, and
  84.      * therefore moves along with the main form. (Pop-ups don't do this
  85.      * easily.)
  86.      */
  87.         program_form = XtCreateWidget("programForm",
  88.                 formWidgetClass,
  89.                                 parent_widget,
  90.                                 (ArgList) NULL, 0);
  91.  
  92.         program_display_viewport = XtCreateManagedWidget(
  93.                 "programDisplayViewport",
  94.                                 viewportWidgetClass,
  95.                 program_form,
  96.                                 (ArgList) NULL, 0);
  97.  
  98.         program_display_form = XtCreateManagedWidget("programDisplayForm",
  99.                                 formWidgetClass,
  100.                                 program_display_viewport,
  101.                                 (ArgList) NULL, 0);
  102.  
  103.  
  104.     XtSetArg(args[0], XtNlabel, " ");
  105.     XtSetArg(args[1], XtNstate, TRUE);
  106.     program_anchor = XtCreateManagedWidget("programSelection",
  107.                 toggleWidgetClass,
  108.                 program_display_form,
  109.                 (ArgList) args, 2);
  110.     XtAddCallback (program_anchor, XtNcallback, cb_move_program_ptr, NULL);
  111.  
  112.  
  113.     XtSetArg(args[0], XtNfromVert, program_display_viewport);
  114.     clear_button = XtCreateManagedWidget("Clear",
  115.                 commandWidgetClass,
  116.                 program_form,
  117.                 (ArgList) args, 1);
  118.     XtAddCallback (clear_button, XtNcallback, cb_clear_program, NULL);
  119.  
  120.     XtSetArg(args[0], XtNfromVert, program_display_viewport);
  121.     XtSetArg(args[1], XtNfromHoriz, clear_button);
  122.     cancel_button = XtCreateManagedWidget("Cancel",
  123.                 commandWidgetClass,
  124.                 program_form,
  125.                 (ArgList) args, 2);
  126.     XtAddCallback (cancel_button, XtNcallback, cb_cancel_program, NULL);
  127.  
  128.  
  129.     XtSetArg(args[0], XtNfromVert, program_display_viewport);
  130.     XtSetArg(args[1], XtNfromHoriz, cancel_button);
  131.     save_button = XtCreateManagedWidget("Save",
  132.                 commandWidgetClass,
  133.                 program_form,
  134.                 (ArgList) args, 2);
  135.     XtAddCallback (save_button, XtNcallback, cb_save_program, NULL);
  136.  
  137.  
  138.     XtSetArg(args[0], XtNfromVert, clear_button);
  139.         track_select_form = XtCreateManagedWidget("selectForm",
  140.                 formWidgetClass,
  141.                 program_form,
  142.                 (ArgList) args, 1);
  143.  
  144.  
  145.     for (i = 1; i <= 9; i++)
  146.     {
  147.         sprintf(namestr, "%d",i);
  148.         trackbuttons[i-1] = XtCreateManagedWidget(namestr,
  149.                     commandWidgetClass,
  150.                     track_select_form,
  151.                     (ArgList) NULL, 0);
  152.                 
  153.     }
  154.  
  155.     XtAddCallback (trackbuttons[0], XtNcallback, cb_trackbuttons, NULL);
  156.  
  157.     for (i = 1; i < 9; i++)
  158.     {
  159.         XtSetArg(args[0], XtNfromHoriz, trackbuttons[i-1]);
  160.         XtSetValues(trackbuttons[i], args, 1);
  161.         XtAddCallback (trackbuttons[i], XtNcallback, cb_trackbuttons, NULL);
  162.     }    
  163.  
  164.     XtSetArg(args[0], XtNfromVert, trackbuttons[0]);
  165.     plus10_button = XtCreateManagedWidget("+10",
  166.                 commandWidgetClass,
  167.                 track_select_form,
  168.                 (ArgList) args, 1);
  169.     XtAddCallback (plus10_button, XtNcallback, cb_add_10, NULL);
  170.  
  171.     XtSetArg(args[0], XtNfromVert, trackbuttons[0]);
  172.     XtSetArg(args[1], XtNfromHoriz, plus10_button);
  173.     new_track_button = XtCreateManagedWidget("  ",
  174.                 commandWidgetClass,
  175.                 track_select_form,
  176.                 (ArgList) args, 2);
  177.     XtAddCallback (new_track_button, XtNcallback, cb_new_track, NULL);
  178.  
  179.     XtSetArg(args[0], XtNfromVert, trackbuttons[0]);
  180.     XtSetArg(args[1], XtNfromHoriz, trackbuttons[6]);
  181.     all_button = XtCreateManagedWidget("All",
  182.                 commandWidgetClass,
  183.                 track_select_form,
  184.                 (ArgList) args, 2);
  185.     XtAddCallback (all_button, XtNcallback, cb_program_all, NULL);
  186.  
  187. }
  188.  
  189. void
  190. popup_program_form (widget, topLevel, call_data)
  191. Widget        widget;
  192. Widget        topLevel;
  193. XtPointer    call_data;
  194. {
  195.         Arg             args[2];
  196.     int        i;
  197.     char        *progstr;
  198.     char        *token;
  199.     int        track;        
  200.  
  201.     extern FILE     *disc_info;
  202.  
  203.  
  204.     cdi.selection = NULL;
  205.  
  206.     /* load saved program (if any) */
  207.     if (disc_info != NULL)
  208.     {
  209.         /* copy "open" program str for tokenization */
  210.         progstr = strdup(program_str);    
  211.         token = strtok(progstr, "-");     /* find 1st programmed track */
  212.         if (token != NULL)
  213.         {
  214.             debug_printf(1, "using stored program\n");
  215.             while (token != NULL)
  216.             {
  217.                 sscanf(token, "%d",&track); /* convert to # */
  218.                 program_add_track((unsigned char)track);
  219.                 token = strtok(NULL,"-"); /* get next track str */
  220.             }
  221.         }
  222.     }
  223.  
  224.     /* clear sensitivity for all */
  225.     for (i=0; i < 9; i++)
  226.     {
  227.         XtSetArg(args[0], XtNsensitive, FALSE);
  228.         XtSetValues(trackbuttons[i], args, 1);
  229.     }
  230.  
  231.     XtSetArg(args[0], XtNsensitive, FALSE);
  232.     XtSetValues(plus10_button, args, 1);
  233.     XtSetValues(new_track_button, args, 1);
  234.  
  235.     for (i = 0; (i < 9) && (i < cdi.maxtrack); i++)
  236.     {
  237.         /* set sensitivity for active buttons */
  238.         XtSetArg(args[0], XtNsensitive, TRUE);
  239.         XtSetValues(trackbuttons[i], args, 1);
  240.     }
  241.     if (cdi.maxtrack > 9)
  242.     {
  243.         XtSetArg(args[0], XtNsensitive, TRUE);
  244.         XtSetValues(plus10_button, args, 1);
  245.     }
  246.  
  247.  
  248.     XtManageChild(program_form);
  249. }
  250.  
  251.  
  252.  
  253. void 
  254. make_program_button(node, next_to, label)
  255. struct    prognode *node;
  256. Widget    next_to;
  257. char    label[];
  258. {
  259.     Arg    args[10];
  260.     char    name[2];
  261.     int    i = 0;
  262.  
  263.     XtSetArg(args[i], XtNfromHoriz, next_to); i++;
  264.     XtSetArg(args[i], XtNlabel, label); i++;
  265.     XtSetArg(args[i], XtNradioGroup, program_anchor); i++;
  266.     XtSetArg(args[i], XtNstate, TRUE); i++; /* activates *this* button */
  267.  
  268.     node->button = XtCreateManagedWidget("programSelection",
  269.                 toggleWidgetClass,
  270.                 program_display_form,
  271.                 (ArgList) args, i);
  272.     XtAddCallback(node->button, XtNcallback, cb_move_program_ptr, 
  273.               (XtPointer) node);
  274.  
  275.     if (node->next != NULL) /* then reposition widget following */
  276.     {
  277.         XtSetArg(args[0], XtNfromHoriz, node->button);
  278.         XtSetValues(node->next->button, args, 1);
  279.     }    
  280. }
  281.  
  282. void 
  283. program_add_track (track)
  284. unsigned char    track;
  285. {
  286.     struct prognode    *insert_point, *new, *next;
  287.     Arg    args[10];
  288.     char    *p;
  289.     char    label[3];
  290.     int    i;
  291.  
  292.     XawFormDoLayout (program_display_form, FALSE);
  293.  
  294.     if (cdi.program == NULL)
  295.     {
  296.         new = (struct prognode *) malloc(sizeof(struct prognode));
  297.         new->track = track;
  298.         new->next = NULL;
  299.         new->prev = NULL;
  300.         current_node = cdi.program = new;
  301.         cdi.lastprog = 1;
  302.  
  303.         sprintf(label, "%d", track);
  304.         make_program_button(new, program_anchor, label);
  305.     }
  306.  
  307.     else if (current_node == NULL) /* pre-insert */
  308.     {
  309.         new = (struct prognode *) malloc(sizeof(struct prognode));
  310.             new->track = track;
  311.             new->next = cdi.program;
  312.             new->prev = NULL;
  313.         current_node = cdi.program->prev = new;
  314.         cdi.program = cdi.program->prev;
  315.         cdi.lastprog++;
  316.  
  317.         sprintf(label, "%d", track);
  318.         make_program_button(new, program_anchor, label);
  319.  
  320.         sprintf(label, "-%d", new->next->track);
  321.         XtSetArg(args[0], XtNlabel, label);
  322.         XtSetValues(new->next->button, args, 1);
  323.     }
  324.     else
  325.     {
  326.         insert_point = cdi.program;
  327.  
  328.         while ((insert_point->next != NULL) && 
  329.            (insert_point != current_node))
  330.          insert_point = insert_point->next;
  331.  
  332.         new = (struct prognode *) malloc(sizeof(struct prognode));
  333.         new->track = track;
  334.         new->next = insert_point->next;
  335.         new->prev = insert_point;
  336.         if (new->next != NULL)
  337.             new->next->prev = new; /* complete link back */
  338.  
  339.         cdi.lastprog++;
  340.         current_node = insert_point->next = new;
  341.  
  342.         sprintf(label, "-%d", track);
  343.         make_program_button(new, insert_point->button, label);
  344.     }
  345.  
  346.     next = cdi.program;
  347.     sprintf(program_str, "%d", next->track);
  348.     for (i = 1; i < cdi.lastprog; i++)
  349.     {
  350.         next = next->next;
  351.         sprintf(program_str, "%s-%d", program_str, next->track);
  352.     }
  353.  
  354.  
  355.     XawFormDoLayout (program_display_form, TRUE);
  356.  
  357.  
  358.     if (cdi.state & CDROM_STATE_PAUSE) 
  359.     {
  360.         cdi.selection = new;
  361.         cdi.curtrack = new->track;
  362.         track_button_update();
  363.         timer_button_update();
  364.     }
  365. }
  366.         
  367. void 
  368. program_delete_track (node)
  369. struct prognode    *node;
  370. {
  371.     int i;
  372.     Arg    args[2];
  373.     char    *p;
  374.     char    label[3];
  375.  
  376.     if (cdi.program == NULL)
  377.         return;
  378.     
  379.     if (node->prev != NULL)
  380.     {
  381.         node->prev->next = node->next;
  382.         current_node = node->prev;
  383.         XtSetArg(args[0], XtNstate, True);
  384.         XtSetValues(current_node->button, args, 1);
  385.  
  386.         XtSetArg(args[0], XtNfromHoriz, node->prev->button);
  387.     }
  388.     else
  389.     {
  390.         cdi.program = node->next;
  391.         current_node = cdi.program;
  392.         if (current_node != NULL)
  393.         {
  394.             sprintf(label, "%d", current_node->track);
  395.             XtSetArg(args[0], XtNlabel, label);
  396.             XtSetArg(args[1], XtNstate, True);
  397.             XtSetValues(current_node->button, args, 2);
  398.  
  399.             XtSetArg(args[0], XtNfromHoriz, program_anchor);
  400.  
  401.         }
  402.         else
  403.         {
  404.             XtSetArg(args[0], XtNstate, True);
  405.             XtSetValues(program_anchor, args, 1);
  406.         }
  407.     }
  408.  
  409.     if (node->next != NULL)
  410.     {
  411.         node->next->prev = node->prev;
  412.         XtSetValues(node->next->button, args, 1);
  413.     }
  414.  
  415.  
  416.     XtDestroyWidget(node->button);
  417.     free(node);
  418.  
  419.     cdi.lastprog--;
  420.  
  421.     if (cdi.program == NULL)
  422.     {
  423.         program_str[0] = '\0';
  424.         cdi.selection = NULL;
  425.     }
  426.     else
  427.     {
  428.         cdi.selection = current_node;
  429.  
  430.         if (cdi.state & CDROM_STATE_PAUSE) 
  431.         {
  432.         cdi.curtrack = current_node->track;
  433.             track_button_update();
  434.             timer_button_update();
  435.         }
  436.  
  437.         node = cdi.program;
  438.         sprintf(program_str, "%d", node->track);
  439.         for (i = 1; i < cdi.lastprog; i++)
  440.         {
  441.         node = node->next;
  442.         sprintf(program_str, "%s-%d", program_str, node->track);
  443.         }
  444.     }
  445.  
  446. }
  447.  
  448.         
  449. int
  450. program_time_remaining()
  451. {
  452.     struct prognode *node;
  453.     int        time_remaining = 0;
  454.  
  455.     if ((cdi.program == NULL) || (cdi.selection == NULL))
  456.         return (0);
  457.         
  458.     node = cdi.selection;
  459.     while (node != NULL)
  460.     {
  461.         time_remaining += cdi.times[node->track - 1];
  462.         node = node->next;
  463.     }
  464.     time_remaining -= cdi.duration;
  465.     return (time_remaining);
  466. }
  467.  
  468.  
  469. unsigned char
  470. program_goto_next_track()
  471. {
  472.     Arg    arg;
  473.     Boolean    already_on;
  474.  
  475.     if (cdi.program == NULL)
  476.         return (0);
  477.     else if (cdi.selection == NULL)
  478.         cdi.selection = cdi.program;
  479.     else if (cdi.selection->next == NULL)
  480.     {
  481.         cdi.selection = NULL;
  482.         return (0);
  483.     }
  484.     else
  485.         cdi.selection = cdi.selection->next;
  486.     
  487.  
  488.     XtSetArg(arg, XtNstate, &already_on);
  489.     XtGetValues(cdi.selection->button, &arg, 1);
  490.     if (already_on == FALSE)
  491.     {
  492.         XtSetArg(arg, XtNstate, TRUE);
  493.         XtSetValues(cdi.selection->button, &arg, 1);
  494.     }
  495.  
  496.     pgm_button_set();
  497.     return(cdi.selection->track);
  498. }
  499.  
  500. unsigned char
  501. program_resume()
  502. {
  503.     unsigned char    track;
  504.  
  505.     if (cdi.program != NULL)
  506.     {
  507.         if (cdi.selection == NULL)
  508.         track = program_goto_next_track();
  509.         else
  510.         track = cdi.selection->track;
  511.     }
  512.     else
  513.         track = cdi.curtrack;
  514.     pgm_button_set();
  515.  
  516.     return(track);
  517. }
  518.  
  519.  
  520. unsigned char
  521. program_goto_prev_track()
  522. {
  523.     Arg    arg;
  524.     Boolean    already_on;
  525.  
  526.     if ((cdi.program == NULL) || (cdi.selection->prev == NULL))
  527.         return (0);
  528.  
  529.     cdi.selection = cdi.selection->prev;
  530.  
  531.     XtSetArg(arg, XtNstate, &already_on);
  532.     XtGetValues(cdi.selection->button, &arg, 1);
  533.     if (already_on == FALSE)
  534.     {
  535.         XtSetArg(arg, XtNstate, TRUE);
  536.         XtSetValues(cdi.selection->button, &arg, 1);
  537.     }
  538.  
  539.     pgm_button_set();
  540.     return (cdi.selection->track);
  541. }
  542.  
  543. unsigned char
  544. program_next_track()
  545. {
  546.     if (cdi.program == NULL)
  547.         return (0);
  548.  
  549.     else if (cdi.selection == NULL)
  550.         return (cdi.program->track);
  551.  
  552.     else if (cdi.selection->next == NULL)
  553.         return (0);
  554.     else
  555.         return (cdi.selection->next->track);
  556.  
  557. }
  558.  
  559. unsigned char
  560. program_prev_track()
  561. {
  562.     if ((cdi.program == NULL) || (cdi.selection == NULL) ||
  563.         (cdi.selection->prev == NULL))
  564.         return (0);
  565.  
  566.     else 
  567.         return (cdi.selection->prev->track);
  568.  
  569. }
  570.         
  571. void
  572. clear_program()
  573. {
  574.     Arg    arg;
  575.  
  576.     /* clear new_track button and deactivate */
  577.     XtSetArg(arg, XtNlabel, "  ");
  578.     XtSetValues(new_track_button, &arg, 1);
  579.     XtSetArg(arg, XtNsensitive, False);
  580.     XtSetValues(new_track_button, &arg, 1);
  581.     adding_to_new_track = False;
  582.  
  583.     if (cdi.program == NULL)
  584.         return;
  585.  
  586.     cdi.selection = cdi.program;
  587.     while (cdi.selection->next != NULL)
  588.     {
  589.         cdi.program = cdi.program-> next;
  590.         XtDestroyWidget(cdi.selection->button);
  591.         free(cdi.selection);
  592.         cdi.selection = cdi.program;
  593.     }
  594.     XtDestroyWidget(cdi.selection->button);
  595.     free(cdi.selection);
  596.     cdi.selection = cdi.program = NULL;
  597.     cdi.lastprog = 0;
  598.     XtSetArg(arg, XtNstate, True);
  599.     XtSetValues(program_anchor, &arg, 1);
  600.  
  601.     program_str[0]= '\0'; /* clear "store" string */
  602.  
  603. }
  604.  
  605. void
  606. program_cancel()
  607. {
  608.     debug_printf(1, "program mode cancelled\n");
  609.     clear_program();
  610.  
  611.     XtUnmanageChild(program_form);
  612.     pgm_button_reset();
  613.     timer_button_reset();
  614.     timer_button_update();
  615.     cdi.state &= ~CDROM_STATE_PROGRAM;
  616. }
  617.  
  618. void    
  619. cb_move_program_ptr(widget, node, call_data)
  620. Widget        widget;
  621. struct prognode *node;
  622. XtPointer    call_data;
  623. {
  624.     /*
  625.      * I cannot get XawToggleGetCurrent to work at all, so this
  626.      * is a bastardized way of doing this:
  627.      */
  628.  
  629.     Arg    arg;
  630.     Boolean    state;
  631.  
  632.     XtSetArg(arg, XtNstate, &state);
  633.     XtGetValues(widget, &arg, 1);
  634.  
  635.     if (state == True)
  636.     {
  637.         if ((current_node == node) && (current_node != NULL))
  638.         {
  639.         debug_printf(1, "deleting selection from program\n");
  640.         program_delete_track(node);
  641.         }
  642.         else
  643.         {
  644.             current_node = node;
  645.  
  646.         if ((current_node != NULL) &&
  647.             ((cdi.state & CDROM_STATE_PAUSE) ||
  648.              ((cdi.state & CDROM_STATE_PLAY) == 0)))
  649.         {
  650.             cdi.selection = node;
  651.             cdi.curtrack = node->track;
  652.                 track_button_update();
  653.                 timer_button_update();
  654.         }
  655.         }
  656.     }
  657.  
  658. }
  659.  
  660.  
  661. static void
  662. cb_program_all(widget, client_data, call_data)
  663. Widget        widget;
  664. XtPointer    client_data;
  665. XtPointer    call_data;
  666. {
  667.     Arg    arg;
  668.     int i;
  669.  
  670.     clear_program(); 
  671.  
  672.     debug_printf(1, "program replaced by in-sequence track list\n");
  673.     for (i = 1; i <= cdi.maxtrack; i++)
  674.         program_add_track ((unsigned char) i);
  675. }
  676.  
  677. static void
  678. cb_clear_program (widget, client_data, call_data)
  679. Widget        widget;
  680. XtPointer    client_data;
  681. XtPointer    call_data;
  682. {
  683.     clear_program(); /* get rid of program */
  684.     debug_printf(1, "program cleared\n");
  685. }
  686.  
  687. static void
  688. cb_cancel_program (widget, client_data, call_data)
  689. Widget        widget;
  690. XtPointer    client_data;
  691. XtPointer    call_data;
  692. {
  693.     program_cancel(); /* get rid of program and form */
  694. }
  695.  
  696. void
  697. cb_save_program (widget, client_data, call_data)
  698. Widget        widget;
  699. XtPointer    client_data;
  700. XtPointer    call_data;
  701. {
  702.     Arg    arg;
  703.     char    *progstr;
  704.     extern FILE    *disc_info;
  705.  
  706.     disc_info = fopen(info_filename, "w+"); /* open for r/w */
  707.     if (disc_info == NULL) {
  708.         fprintf(stderr,"Can't open save file %s\n",info_filename);
  709.         perror("cb_save_program");
  710.         return;
  711.     }
  712.     fprintf(disc_info, "Title:%s\nProgram: %s\n", disc_title, program_str);
  713.     fflush(disc_info);
  714.  
  715.     debug_printf(1, "program saved to %s\n", info_filename);
  716. }
  717.  
  718. void
  719. add_to_new_track (number)
  720. int    number;
  721. {
  722.     Arg    arg;
  723.     char    *namestr;
  724.     int    track = 0;
  725.  
  726.     /* an apparent bug in my system won't allow the auto-display of this
  727.      * label change without explicit forcing redraw via something other
  728.      * than the label itself
  729.      */
  730.     XtSetArg(arg, XtNsensitive, False);
  731.     XtSetValues(new_track_button, &arg, 1);
  732.  
  733.     XtSetArg(arg, XtNlabel, &namestr);
  734.     XtGetValues(new_track_button, &arg, 1);
  735.     if (namestr[0] != ' ')
  736.         sscanf (namestr, "%d", &track);
  737.     track += number;
  738.     sprintf(namestr, "%d\n", track);
  739.     XtSetArg(arg, XtNlabel, namestr);
  740.     XtSetValues(new_track_button, &arg, 1);
  741.  
  742.     /* reset the sensitive flage for redraw */
  743.     XtSetArg(arg, XtNsensitive, True);
  744.     XtSetValues(new_track_button, &arg, 1);
  745. }
  746.  
  747. static void
  748. cb_add_10(widget, client_data, call_data)
  749. Widget        widget;
  750. XtPointer    client_data;
  751. XtPointer    call_data;
  752. {
  753.     Arg    arg;
  754.     char    *namestr;
  755.     int    track = 0;
  756.  
  757.     XtSetArg(arg, XtNsensitive, True);
  758.     XtSetValues(new_track_button, &arg, 1);
  759.     adding_to_new_track = True;
  760.     add_to_new_track(10);
  761. }
  762.  
  763. static void
  764. cb_new_track(widget, client_data, call_data)
  765. Widget        widget;
  766. XtPointer    client_data;
  767. XtPointer    call_data;
  768. {
  769.     Arg    arg;
  770.     char    *namestr;
  771.     int    track;
  772.  
  773.     XtSetArg(arg, XtNlabel, &namestr);
  774.     XtGetValues(widget, &arg, 1);
  775.     sscanf (namestr, "%d", &track);
  776.  
  777.     if ((track >= cdi.mintrack) && (track <= cdi.maxtrack))
  778.     {
  779.         debug_printf(1, "adding track %d to program\n", track);
  780.         program_add_track((unsigned char) track);
  781.     }
  782.     XtSetArg(arg, XtNlabel, "  ");
  783.     XtSetValues(new_track_button, &arg, 1);
  784.     XtSetArg(arg, XtNsensitive, False);
  785.     XtSetValues(new_track_button, &arg, 1);
  786.     adding_to_new_track = False;
  787. }
  788.  
  789.  
  790. static void
  791. cb_trackbuttons(widget, client_data, call_data)
  792. Widget        widget;
  793. XtPointer    client_data;
  794. XtPointer    call_data;
  795. {
  796.     Arg    arg;
  797.     char    *namestr;
  798.     int    track;
  799.     Boolean state;
  800.  
  801.     XtSetArg(arg, XtNlabel, &namestr);
  802.     XtGetValues(widget, &arg, 1);
  803.     sscanf (namestr, "%d", &track);
  804.  
  805.     if (adding_to_new_track)
  806.         add_to_new_track(track);
  807.     else
  808.     {
  809.         debug_printf(1, "adding track %d to program\n", track);
  810.         program_add_track((unsigned char) track);
  811.     }
  812.  
  813. }
  814.